import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { defineConfig, loadEnv } from 'vite'
import dayjs from 'dayjs'
import type { PluginOption } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vueLegacy from '@vitejs/plugin-legacy'
import VueDevTools from 'vite-plugin-vue-devtools'
import Unocss from 'unocss/vite'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import { vitePluginFakeServer } from 'vite-plugin-fake-server'
import Layouts from 'vite-plugin-vue-meta-layouts'
import Pages from 'vite-plugin-pages'
import { compression } from 'vite-plugin-compression2'
import type { Format } from 'archiver'
import archiver from 'archiver'
import TurboConsole from 'unplugin-turbo-console/vite'
import banner from 'vite-plugin-banner'
import pkg from './package.json'

export default async ({ mode, command }: any) => {
  const env = loadEnv(mode, process.cwd())
  // 全局 scss 资源
  // const scssResources: string[] = []
  // fs.readdirSync('src/styles/resources').forEach((dirname) => {
  //   if (fs.statSync(`src/styles/resources/${dirname}`).isFile()) {
  //     scssResources.push(`@use "src/styles/resources/${dirname}" as *;`)
  //   }
  // })
  return defineConfig({
    base: './',
    // 开发服务器选项 https://cn.vitejs.dev/config/server-options
    server: {
      port: 8999,
      proxy: {
        '/proxy': {
          target: env.VITE_APP_API_BASEURL,
          changeOrigin: command === 'serve' && env.VITE_OPEN_PROXY === 'true',
          rewrite: path => path.replace(/\/proxy/, ''),
        },
      },
    },
    // 构建选项 https://cn.vitejs.dev/config/build-options
    build: {
      outDir: 'dist',
      sourcemap: env.VITE_BUILD_SOURCEMAP === 'true',
    },
    define: {
      __SYSTEM_INFO__: JSON.stringify({
        pkg: {
          dependencies: pkg.dependencies,
          devDependencies: pkg.devDependencies,
        },
        lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
      }),
    },
    plugins: createVitePlugins(env, command === 'build'),
    resolve: {
      alias: {
        '@': path.resolve(__dirname, 'src'),
        '#': path.resolve(__dirname, 'src/types'),
      },
    },
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: '@use "@/styles/resources/variables.scss" as *;',
        },
      },
    },
  })
}

function sleep(ms: number | undefined) {
  return new Promise(resolve => setTimeout(resolve, ms))
}

function createVitePlugins(viteEnv: Record<string, string>, isBuild = false) {
  const vitePlugins: (PluginOption | PluginOption[])[] = [
    vue(),
    vueJsx(),
    vueLegacy({
      renderLegacyChunks: false,
      modernPolyfills: ['es.array.at', 'es.array.find-last'],
    }),

    // https://github.com/vuejs/devtools-next
    viteEnv.VITE_OPEN_DEVTOOLS === 'true' && VueDevTools(),

    Unocss(),

    // https://github.com/vbenjs/vite-plugin-svg-icons
    createSvgIconsPlugin({
      iconDirs: [path.resolve(process.cwd(), 'src/assets/icons/')],
      symbolId: 'icon-[dir]-[name]',
      svgoOptions: isBuild,
    }),

    // https://github.com/condorheroblog/vite-plugin-fake-server
    vitePluginFakeServer({
      logger: !isBuild,
      include: 'src/mock',
      infixName: false,
      enableProd: isBuild && viteEnv.VITE_BUILD_MOCK === 'true',
    }),

    // https://github.com/dishait/vite-plugin-vue-meta-layouts
    Layouts({
      defaultLayout: 'index',
    }),

    // https://github.com/hannoeru/vite-plugin-pages
    Pages({
      dirs: 'src/views',
      exclude: ['**/components/**/*.vue'],
    }),

    // https://github.com/nonzzz/vite-plugin-compression
    isBuild
    && viteEnv.VITE_BUILD_COMPRESS?.split(',').includes('gzip')
    && compression(),
    isBuild
    && viteEnv.VITE_BUILD_COMPRESS?.split(',').includes('brotli')
    && compression({
      exclude: [/\.(br)$/, /\.(gz)$/],
      algorithm: 'brotliCompress',
    }),

    (function () {
      let outDir: string
      return {
        name: 'vite-plugin-archiver',
        apply: 'build',
        configResolved(resolvedConfig) {
          outDir = resolvedConfig.build.outDir
        },
        async closeBundle() {
          if (['zip', 'tar'].includes(viteEnv.VITE_BUILD_ARCHIVE)) {
            await sleep(1000)
            const archive = archiver(viteEnv.VITE_BUILD_ARCHIVE as Format, {
              ...(viteEnv.VITE_BUILD_ARCHIVE === 'zip' && {
                zlib: { level: 9 },
              }),
              ...(viteEnv.VITE_BUILD_ARCHIVE === 'tar' && {
                gzip: true,
                gzipOptions: { level: 9 },
              }),
            })
            const output = fs.createWriteStream(
              `${outDir}.${dayjs().format('YYYY-MM-DD-HH-mm-ss')}.${
                viteEnv.VITE_BUILD_ARCHIVE === 'zip' ? 'zip' : 'tar.gz'
              }`,
            )
            archive.pipe(output)
            archive.directory(outDir, false)
            archive.finalize()
          }
        },
      }
    })(),

    // https://github.com/unplugin/unplugin-turbo-console
    TurboConsole(),

    // https://github.com/chengpeiquan/vite-plugin-banner
    banner('wei-admin develop'),
    {
      name: 'vite-plugin-debug-plugin',
      transform: (code, id) => {
        if (/src\/main.ts$/.test(id)) {
          if (viteEnv.VITE_APP_DEBUG_TOOL === 'eruda') {
            code = code.concat(`
              import eruda from 'eruda'
              eruda.init()
            `)
          }
          else if (viteEnv.VITE_APP_DEBUG_TOOL === 'vconsole') {
            code = code.concat(`
              import VConsole from 'vconsole'
              new VConsole()
            `)
          }
          return {
            code,
            map: null,
          }
        }
      },
    },
    {
      name: 'vite-plugin-disable-devtool',
      transform: (code, id) => {
        if (/src\/main.ts$/.test(id)) {
          if (viteEnv.VITE_APP_DISABLE_DEVTOOL === 'true') {
            code = code.concat(`
              import DisableDevtool from 'disable-devtool'
              DisableDevtool({
                md5: '1a79a4d60de6718e8e5b326e338ae533',
              })
            `)
          }
          return {
            code,
            map: null,
          }
        }
      },
    },
  ]
  return vitePlugins
}
